package com.jie.flink.cdc.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author zhanggj
 * @data 2022/5/30
 */
public class JacksonConvertor implements JsonConvertor {

    private static final ObjectMapper defaultObjectMapper =  new ObjectMapper() {{
        // 序列化忽略非空
        this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        // 只是反序列化提供下划线转驼峰，序列化还是驼峰
        this.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);
        // 处理空字符为空对象
        this.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        // 处理数组为空对象
        this.enable(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
        // 忽略额外 json 结构
        this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }};




    @Override
    public <T> List<T> deserializeToArray(String json, Class<T> classOfT) throws Exception {
        return defaultObjectMapper.readValue(json, TypeFactory.defaultInstance().constructParametricType(ArrayList.class,classOfT));
    }

    @Override
    public <T> List<T> deserializeToArray(String json, Type type) throws Exception {
        return defaultObjectMapper.readValue(json, TypeFactory.defaultInstance().constructParametricType(ArrayList.class,TypeFactory.defaultInstance().constructType(type)));
    }

    @Override
    public <T> Map<String, Object> convertToMap(T t) throws Exception {
        return defaultObjectMapper.convertValue(t, Map.class);
    }

    @Override
    public Map<String, Object> convertToMap(String json) throws Exception {
        return defaultObjectMapper.readValue(json, Map.class);
    }

    @Override
    public <T> T convertToBean(Map<String, Object> map, Class<T> classOfT) throws Exception {
        return defaultObjectMapper.convertValue(map, classOfT);
    }

    @Override
    public <T> T convertToBean(Map<String, Object> map, Type type) throws Exception {
        return defaultObjectMapper.convertValue(map, TypeFactory.defaultInstance().constructType(type));
    }

    @Override
    public <T> String serialize(T t) throws Exception {
        return defaultObjectMapper.writeValueAsString(t);

    }

    @Override
    public <T> T deserialize(String json, Class<T> classOfT) throws Exception {
        return defaultObjectMapper.readValue(json, classOfT);
    }

    @Override
    public <T> T deserialize(String json, Type type) throws Exception {
        return defaultObjectMapper.readValue(json, defaultObjectMapper.constructType(type));
    }
}
